const proxy = require('koa-server-http-proxy')
const koaJwt = require('koa-jwt')
const Router = require('koa-router')
const koaLogger = require('koa-logger')
const cors = require('koa2-cors')
const Koa = require('koa')
const bodyParser = require('koa-bodyparser')

const mongoose = require('mongoose')

const config = require('./config')
const tools = require('./utils/tools')
const logger = require('./utils/logger');
const templateRouter = require('./router/templateRouter')
const recordRouter = require('./router/recordRouter')
const dictRouter = require('./router/dictRouter')
const mockRouter = require('./router/mockRouter')
const printRouter = require('./router/printRouter')
const msgRouter = require('./router/msgRouter')

const WebSocket = require('ws');
const WebSocketServer = WebSocket.Server;

mongoose.connect(config.database, {useNewUrlParser: true}, err => {
  if (err) {
    console.log('Connection Error:' + err)
  } else {
    console.log('Connection success!')
  }
})

const app = new Koa()

app.use(cors());

app.use(koaLogger());

app.use((ctx, next) => {
  return next().catch((err) => {
    if (401 == err.status) {
      ctx.status = 401;
      ctx.body = {
        error: err.originalError ? err.originalError.message : err.message
      };
    } else {
      ctx.status = err.status || err.code || 500;
      ctx.body = {
        success: false,
        message: err.message,
      };
    }
  });
});

const apiRouter = new Router({
  prefix: '/sys'
});

apiRouter.get('/sm', ctx => {
  ctx.body = {
    test: 'success'
  };
});

let server = app.listen(3000)

let wss = new WebSocketServer({
  server: server
})

app.use(async (ctx, next) => {
  ctx.wss = wss;
  await next();
})

app.use(koaJwt({ secret: new Buffer(config.secret, 'base64'), algorithms: ['HS512'] }).unless({ path: [/^\/public/, /^\/api\/user\/login/] }));

app.use(proxy('/api', {target: 'http://localhost:8085', changeOrigin: true}))

app.use(bodyParser({formLimit: "50mb"}));

app.use(apiRouter.routes())

app.use(templateRouter.routes())

app.use(recordRouter.routes())

app.use(dictRouter.routes())

app.use(mockRouter.routes())

app.use(printRouter.routes())

app.use(msgRouter.routes())

// let toEvent = message => {
//   try {
//     var event = JSON.parse(message)
//     this.emit(event.type, event.payload)
//   } catch(err) {
//     console.log('not an event' , err)
//   }
// }

// wss.on('connection', async ws => {
//   ws.on('message', toEvent)
//     .on('authenticate', async data => {
//       console.log(data)
//       let decoded = await jwt.verify(data.token, new Buffer(config.secret, 'base64'), { algorithms: ['HS512'] })
//       ws.send('something');
//     })
// })

wss.on('connection', async (ws, req) => {
  let user = await tools.parseUser(req)
  if (!user) {
      // Cookie不存在或无效，直接关闭WebSocket:
      ws.close(4001, 'Invalid user')
  }
  console.log(`${user.opName} 已连线`)
  // 识别成功，把user绑定到该WebSocket对象:
  ws.user = user
  // 绑定WebSocketServer对象:
  ws.wss = wss

  ws.on('message', message => {
    if (message && message.trim()) {
      wss.clients.forEach(client => {
        client.send('sb')
      })
    }
  })

  ws.on('close', (code, message) => {
    console.log(`连接关闭了 code: ${code}, message: ${message}`)
  })
})

logger.info('应用服务器启动,监听端口: 3000')